package org.framework.customutil;

import java.beans.PropertyEditorSupport;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * @Title: DateUtils.java .<br>
 * @Package org.framework.customutil .<br>
 * @Description: 时间操作定义类 .<br>
 * @author 郑成功 .<br>
 * @email a876459952@qq.com .<br>
 * @date 2018-6-7 下午8:48:44.<br>
 * @version V1.0.<br>
 */
public class DateUtils extends PropertyEditorSupport {
	// 各种时间格式
	public static final SimpleDateFormat date_sdf = new SimpleDateFormat("yyyy-MM-dd");
	// 各种时间格式
	public static final SimpleDateFormat yyyyMMdd = new SimpleDateFormat("yyyyMMdd");
	// 各种时间格式
	public static final SimpleDateFormat date_sdf_wz = new SimpleDateFormat("yyyy年MM月dd日");
	public static final SimpleDateFormat time_sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
	public static final SimpleDateFormat yyyymmddhhmmss = new SimpleDateFormat("yyyyMMddHHmmss");
	public static final SimpleDateFormat short_time_sdf = new SimpleDateFormat("HH:mm");
	public static final  SimpleDateFormat datetimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	// 以毫秒表示的时间
	private static final long MONTH_IN_MILLIS = 12 * 24 * 3600 * 1000;
	private static final long DAY_IN_MILLIS = 24 * 3600 * 1000;
	private static final long HOUR_IN_MILLIS = 3600 * 1000;
	private static final long MINUTE_IN_MILLIS = 60 * 1000;
	private static final long SECOND_IN_MILLIS = 1000;
	// 指定模式的时间格式
	private static SimpleDateFormat getSDFormat(String pattern) {
		return new SimpleDateFormat(pattern);
	}

	/**
	 * @Description: 当前日历，这里用中国时间表示,以当地时区表示的系统当前日历 .<br>
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午8:54:07.<br>
	 */
	public static Calendar getCalendar() {
		return Calendar.getInstance();
	}

	/**
	 * @Description: 指定毫秒数表示的日历 .<br>
	 * @param millis 毫秒数.<br>
	 * @return 指定毫秒数表示的日历.<br>   
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午8:54:32.<br>
	 */
	public static Calendar getCalendar(long millis) {
		Calendar cal = Calendar.getInstance();
		// --------------------cal.setTimeInMillis(millis);
		cal.setTime(new Date(millis));
		return cal;
	}

	

	/**
	 * @Description: 获取当前日期,系统当前时间 .<br>
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午8:55:02.<br>
	 */
	public static Date getDate() {
		return new Date();
	}

	/**
	 * @Description: 获取指定毫秒数表示的日期 .<br>
	 * @param millis 毫秒数.<br>   
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午8:55:29.<br>
	 */
	public static Date getDate(long millis) {
		return new Date(millis);
	}

	/**
	 * @Description: 时间戳转换为字符串 .<br>
	 * @param time 时间 .<br>
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午8:56:10.<br>
	 */
	public static String timestamptoStr(Timestamp time) {
		Date date = null;
		if (null != time) {
			date = new Date(time.getTime());
		}
		return date2Str(date,date_sdf);
	}

	/**
	 * @Description: 字符串转换时间戳 .<br>
	 * @param str 日期字符串 .<br>
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:06:09.<br>
	 */
	public static Timestamp str2Timestamp(String str) {
		Date date = str2Date(str, date_sdf);
		return new Timestamp(date.getTime());
	}
	
	/**
	 * @Description: 字符串转换成日期 .<br>
	 * @param str 时间字符串.<br>
	 * @param sdf 格式.<br>
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午8:57:34.<br>
	 */
	public static Date str2Date(String str, SimpleDateFormat sdf) {
		if (null == str || "".equals(str)) {
			return null;
		}
		Date date = null;
		try {
			date = sdf.parse(str);
			return date;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * @Description: 日期转换为字符串 .<br>
	 * @param date_sdf 日期格式 .<br>
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午8:58:07.<br>
	 */
	public static String date2Str(SimpleDateFormat date_sdf) {
		Date date=getDate();
		if (null == date) {
			return null;
		}
		return date_sdf.format(date);
	}

	/**
	 * @Description: 格式化时间 .<br>
	 * @param date 日期.<br>
	 * @param format 格式.<br>
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午8:59:01.<br>
	 */
	public static String dateformat(String date,String format){
		SimpleDateFormat sformat = new SimpleDateFormat(format);
		Date _date=null;
		try {
			 _date=sformat.parse(date);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return sformat.format(_date);
	}
	
	
	/**
	 * @Description: 日期转换为字符串 .<br>
	 * @param date 日期 .<br> 
	 * @param date_sdf 日期格式.<br> 
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:02:50.<br>
	 */
	public static String date2Str(Date date, SimpleDateFormat date_sdf) {
		if (null == date) {
			return null;
		}
		return date_sdf.format(date);
	}
	
	/**
	 * @Description: 日期转换为字符串 .<br>
	 * @param format 日期格式.<br> 
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:02:50.<br>
	 */
	public static String getDate(String format) {
		Date date=new Date();
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.format(date);
	}


	/**
	 * @Description: 获取指定毫秒数的时间戳 .<br>
	 * @param millis 毫秒数 .<br>
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:04:26.<br>
	 */
	public static Timestamp getTimestamp(long millis) {
		return new Timestamp(millis);
	}

	/**
	 * @Description: 以字符形式表示的时间戳 .<br>
	 * @param time 毫秒数
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:06:50.<br>
	 */
	public static Timestamp getTimestamp(String time) {
		return new Timestamp(Long.parseLong(time));
	}

	/**
	 * @Description: 获取系统当前的时间戳 .<br>
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:07:19.<br>
	 */
	public static Timestamp getTimestamp() {
		return new Timestamp(new Date().getTime());
	}

	/**
	 * @Description: 获取指定日期的时间戳 .<br>
	 * @param date 指定日期 .<br>
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:07:37.<br>
	 */
	public static Timestamp getTimestamp(Date date) {
		return new Timestamp(date.getTime());
	}

	/**
	 * @Description: 获取指定日历的时间戳 .<br>
	 * @param cal 指定日历 .<br>   
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:08:11.<br>
	 */
	public static Timestamp getCalendarTimestamp(Calendar cal) {
		return new Timestamp(cal.getTime().getTime());
	}

	/**
	 * @Description: 获取时间戳 .<br>
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:09:03.<br>
	 */
	public static Timestamp gettimestamp() {
		Date dt = new Date();
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String nowTime = df.format(dt);
		java.sql.Timestamp buydate = java.sql.Timestamp.valueOf(nowTime);
		return buydate;
	}


	/**
	 * @Description: 系统时间的毫秒数 .<br>
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:09:34.<br>
	 */
	public static long getMillis() {
		return new Date().getTime();
	}

	/**
	 * @Description: 获取指定日历的毫秒数 .<br>
	 * @param cal 指定日历 .<br>   
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:09:49.<br>
	 */
	public static long getMillis(Calendar cal) {
		return cal.getTime().getTime();
	}

	/**
	 * @Description: 指定日期的毫秒数 .<br>
	 * @param date 指定日期 .<br>
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:10:42.<br>
	 */
	public static long getMillis(Date date) {
		return date.getTime();
	}

	/**
	 * @Description: 指定时间戳的毫秒数 .<br>
	 * @param ts 指定时间戳  .<br>
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:11:09.<br>
	 */
	public static long getMillis(Timestamp ts) {
		return ts.getTime();
	}


	/**
	 * @Description: 默认方式表示的系统当前日期，具体格式：年-月-日 .<br>
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:11:30.<br>
	 */
	public static String formatDate() {
		return date_sdf.format(getCalendar().getTime());
	}
	
	/**
	 * @Description: 获取时间字符串 .<br>
	 * @param formatstr 格式.<br>
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:11:50.<br>
	 */
	public static String getDataString(SimpleDateFormat formatstr) {
		return formatstr.format(getCalendar().getTime());
	}
	
	/**
	 * @Description: 指定日期的默认显示，具体格式：年-月-日 .<br>
	 * @param cal 指定的日期 .<br>   
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:12:13.<br>
	 */
	public static String formatDate(Calendar cal) {
		return date_sdf.format(cal.getTime());
	}

	/**
	 * @Description: 指定日期的默认显示，具体格式：年-月-日 .<br>
	 * @param date 指定的日期  .<br>
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:12:33.<br>
	 */
	public static String formatDate(Date date) {
		return date_sdf.format(date);
	}

	/**
	 * @Description: 指定毫秒数表示日期的默认显示，具体格式：年-月-日 .<br>
	 * @param millis 指定的毫秒数 .<br>
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:12:54.<br>
	 */
	public static String formatDate(long millis) {
		return date_sdf.format(new Date(millis));
	}

	/**
	 * @Description: 默认日期按指定格式显示 .<br>
	 * @param pattern 指定的格式.<br>   
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:13:16.<br>
	 */
	public static String formatDate(String pattern) {
		return getSDFormat(pattern).format(getCalendar().getTime());
	}

	/**
	 * @Description: 指定日期按指定格式显示 .<br>
	 * @param cal 指定的日期 .<br>
	 * @param pattern 指定的格式 .<br>
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:13:45.<br>
	 */
	public static String formatDate(Calendar cal, String pattern) {
		return getSDFormat(pattern).format(cal.getTime());
	}

	/**
	 * @Description:指定日期按指定格式显示 .<br>
	 * @param date 指定的日期 .<br>
	 * @param pattern 指定的格式 .<br>
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:35:50.<br>
	 */
	public static String formatDate(Date date, String pattern) {
		return getSDFormat(pattern).format(date);
	}


	/**
	 * @Description:默认方式表示的系统当前日期，具体格式：年-月-日 时：分.<br>
	 * @return 默认日期按“年-月-日 时：分“格式显示.<br>
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:35:50.<br>
	 */
	public static String formatTime() {
		return time_sdf.format(getCalendar().getTime());
	}

	/**
	 * @Description: 指定毫秒数表示日期的默认显示，具体格式：年-月-日 时：分.<br>
	 * @param millis 指定的毫秒数.<br>
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:35:50.<br>
	 */
	public static String formatTime(long millis) {
		return time_sdf.format(new Date(millis));
	}

	/**
	 * @Description: 指定日期的默认显示，具体格式：年-月-日 时：分.<br>   
	 * @param cal.<br>   
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:35:50.<br>
	 */
	public static String formatTime(Calendar cal) {
		return time_sdf.format(cal.getTime());
	}

	/**
	 * @Description: 指定日期的默认显示，具体格式：年-月-日 时：分 .<br>
	 * @param date 指定的日期.<br>   
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:35:50.<br>
	 */
	public static String formatTime(Date date) {
		return time_sdf.format(date);
	}


	/**
	 * @Description: 默认方式表示的系统当前日期，具体格式：时：分 .<br>
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:35:33.<br>
	 */
	public static String formatShortTime() {
		return short_time_sdf.format(getCalendar().getTime());
	}

	/**
	 * @Description: 指定毫秒数表示日期的默认显示，具体格式：时：分 .<br>
	 * @param millis 指定的毫秒数  .<br>
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:35:05.<br>
	 */
	public static String formatShortTime(long millis) {
		return short_time_sdf.format(new Date(millis));
	}

	/**
	 * @Description: 指定日期的默认显示，具体格式：时：分 .<br>
	 * @param cal 指定的日期 .<br>   
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:34:41.<br>
	 */
	public static String formatShortTime(Calendar cal) {
		return short_time_sdf.format(cal.getTime());
	}

	/**
	 * @Description: 指定日期的默认显示，具体格式：时：分 .<br>
	 * @param date 指定的日期.<br>   
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:34:12.<br>
	 */
	public static String formatShortTime(Date date) {
		return short_time_sdf.format(date);
	}


	/**
	 * @Description: 根据指定的格式将字符串转换成Date 如输入：2003-11-19 11:20:20将按照这个转成时间 .<br>
	 * @param src 将要转换的原始字符窜   .<br>
	 * @param pattern 转换的匹配格式  .<br>
	 * @throws ParseException .<br>   
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:32:52.<br>
	 */
	public static Date parseDate(String src, String pattern)
			throws ParseException {
		return getSDFormat(pattern).parse(src);

	}

	/**
	 * @Description: 根据指定的格式将字符串转换成Date 如输入：2003-11-19 11:20:20将按照这个转成时间 .<br>
	 * @param src 将要转换的原始字符窜   .<br>
	 * @param pattern 转换的匹配格式  .<br>
	 * @throws ParseException .<br>   
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:32:52.<br>
	 */
	public static Calendar parseCalendar(String src, String pattern)
			throws ParseException {

		Date date = parseDate(src, pattern);
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal;
	}

	/**
	 * @Description: 日期相加 .<br>
	 * @param src 字符串日期.<br>
	 * @param pattern 格式.<br>
	 * @param amount 相加数.<br>
	 * @throws ParseException .<br>   
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:32:05.<br>
	 */
	public static String formatAddDate(String src, String pattern, int amount)
			throws ParseException {
		Calendar cal;
		cal = parseCalendar(src, pattern);
		cal.add(Calendar.DATE, amount);
		return formatDate(cal);
	}

	/**
	 * @Description: 根据指定的格式将字符串转换成Date 如输入：2003-11-19 11:20:20将按照这个转成时间 .<br>
	 * @param src  将要转换的原始字符窜 .<br>
	 * @param pattern  转换的匹配格式 .<br>
	 * @throws ParseException .<br>   
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:30:54.<br>
	 */
	public static Timestamp parseTimestamp(String src, String pattern)
			throws ParseException {
		Date date = parseDate(src, pattern);
		return new Timestamp(date.getTime());
	}


	/**
	 * @Description: 计算两个时间之间的差值，根据标志的不同而不同 .<br>
	 * @param flag 计算标志，表示按照年/月/日/时/分/秒等计算(y/m/d/h/mi/s) .<br>
	 * @param calSrc 减数 .<br>
	 * @param calDes 被减数.<br>
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:18:43.<br>
	 */
	@SuppressWarnings("static-access")
	public static int dateDiff(dateFlag flag, Calendar calSrc, Calendar calDes) {

		long millisDiff = getMillis(calSrc) - getMillis(calDes);

		if (flag.equals(dateFlag.y)) {
			return (calSrc.get(calSrc.YEAR) - calDes.get(calDes.YEAR));
		}
		if(flag.equals(dateFlag.m)){
			return (int) (millisDiff / MONTH_IN_MILLIS);
		}
		if (flag.equals(dateFlag.y)) {
			return (int) (millisDiff / DAY_IN_MILLIS);
		}
		if (flag.equals(dateFlag.h)) {
			return (int) (millisDiff / HOUR_IN_MILLIS);
		}

		if (flag.equals(dateFlag.mi)) {
			return (int) (millisDiff / MINUTE_IN_MILLIS);
		}
		if (flag.equals(dateFlag.s)) {
			return (int) (millisDiff / SECOND_IN_MILLIS);
		}
		return 0;
	}
	
	/**
	 * @Title: DateUtils.java .<br>
	 * @Package org.framework.customutil .<br>
	 * @Description: 日期标志 .<br>
	 * @author 郑成功 .<br>
	 * @email a876459952@qq.com .<br>
	 * @date 2018-6-7 下午9:27:07.<br>
	 * @version V1.0.<br>
	 */
	public static enum dateFlag{
		y,m,d,h,mi,s
	}
    
	/**
	 * @Description: 获取年 .<br>
	 * @author 郑成功 .<br>
	 * @date 2018-6-7 下午9:30:12.<br>
	 */
	public static int getYear(){
	    GregorianCalendar calendar=new GregorianCalendar();
	    calendar.setTime(getDate());
	    return calendar.get(Calendar.YEAR);
	}
	
	/**
     * @Description: 根据两个String类型日期，得到xx天xx小时xx分xx秒 .<br>
     * @param str1 时间参数 1 格式：1990-01-01 12:00:00 .<br>
     * @param str2 时间参数 2 格式：2009-01-01 12:00:00 .<br>
     * @param dateFlag flag 只返回到天、时、分、秒 .<br>
     * @return String 返回值为：xx天xx小时xx分xx秒.<br>   
     * @author 郑成功 .<br>
     * @date 2018-6-21 上午8:48:22.<br>
     */
    public static String getDistanceTime(String str1, String str2,dateFlag flag) {  
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
        Date one;  
        Date two;  
        long day = 0;  
        long hour = 0;  
        long min = 0;  
        long sec = 0;  
        try {  
            one = df.parse(str1);  
            two = df.parse(str2);  
            long time1 = one.getTime();  
            long time2 = two.getTime();  
            long diff ;  
            if(time1<time2) {  
                diff = time2 - time1;  
            } else {  
                diff = time1 - time2;  
            }  
            day = diff / (24 * 60 * 60 * 1000);  
            hour = (diff / (60 * 60 * 1000) - day * 24);  
            min = ((diff / (60 * 1000)) - day * 24 * 60 - hour * 60);  
            sec = (diff/1000-day*24*60*60-hour*60*60-min*60);  
        } catch (ParseException e) {  
            e.printStackTrace();  
        } 
        if(flag.equals(dateFlag.d)){
        	return day + "天" ;  
        }else if(flag.equals(dateFlag.h)){
        	return day + "天" + hour + "小时";  
        }else if(flag.equals(dateFlag.mi)){
        	return day + "天" + hour + "小时" + min + "分";  
        }else{
        	return day + "天" + hour + "小时" + min + "分" + sec + "秒"; 
        }
    } 
    
    /**
     * @Description: 根据两个Date类型日期，得到xx天xx小时xx分xx秒 .<br>
     * @param date 时间1 .<br>
     * @param date2 时间2 .<br>
     * @param dateFlag flag 只返回到天、时、分、秒 .<br>
     * @return String 返回值为：xx天xx小时xx分xx秒.<br>   
     * @author 郑成功 .<br>
     * @date 2018-6-21 上午8:48:22.<br>
     */
    public static String getDistanceTime(Date date, Date date2,dateFlag flag) {  
        long day = 0;  
        long hour = 0;  
        long min = 0;  
        long sec = 0;  
        long time1 = date.getTime();  
        long time2 = date2.getTime();  
        long diff ;  
        if(time1<time2) {  
            diff = time2 - time1;  
        } else {  
            diff = time1 - time2;  
        }  
        day = diff / (24 * 60 * 60 * 1000);  
        hour = (diff / (60 * 60 * 1000) - day * 24);  
        min = ((diff / (60 * 1000)) - day * 24 * 60 - hour * 60);  
        sec = (diff/1000-day*24*60*60-hour*60*60-min*60);  
        if(flag.equals(dateFlag.d)){
        	return day + "天" ;  
        }else if(flag.equals(dateFlag.h)){
        	return day + "天" + hour + "小时";  
        }else if(flag.equals(dateFlag.mi)){
        	return day + "天" + hour + "小时" + min + "分";  
        }else{
        	return day + "天" + hour + "小时" + min + "分" + sec + "秒"; 
        }
    } 
    
    /**
     * @Description: 根据时间差，得到xx天xx小时xx分xx秒 .<br>
     * @param duration 时间差 .<br>
     * @return String 返回值为：xx天xx小时xx分xx秒.<br>  
     * @param dateFlag flag 只返回到天、时、分、秒 .<br> 
     * @author 郑成功 .<br>
     * @date 2018-6-21 上午8:48:22.<br>
     */
    public static String getDistanceTime(long duration,dateFlag flag) {  
        long day = 0;  
        long hour = 0;  
        long min = 0;  
        long sec = 0;  
        day = duration / (24 * 60 * 60 * 1000);  
        hour = (duration / (60 * 60 * 1000) - day * 24);  
        min = ((duration / (60 * 1000)) - day * 24 * 60 - hour * 60);  
        sec = (duration/1000-day*24*60*60-hour*60*60-min*60);  
        if(flag.equals(dateFlag.d)){
        	return day + "天" ;  
        }else if(flag.equals(dateFlag.h)){
        	return day + "天" + hour + "小时";  
        }else if(flag.equals(dateFlag.mi)){
        	return day + "天" + hour + "小时" + min + "分";  
        }else{
        	return day + "天" + hour + "小时" + min + "分" + sec + "秒"; 
        }
    } 

}